import socket from "socket.io";

let ctx, subsystems;
let addresses=[];
let waitList=[];
let connecting=[];

function createArgHandler(socket){
    return function(content){
        socket.emit("event", content);
    }
}

function invoke(name, socket){
    setTimeout(async ()=>{
        await subsystems.events.trigger(name, createArgHandler(socket));
        subsystems.events.unlisten(name);
    },0); //event not saved yet.
}

function addToken(token, name){
    if (typeof waitList[token] === "undefined")
        waitList[token] = [];
    waitList[token].push(name);
}

export default {
    listen(eventDef, name){
        let socket=connecting[eventDef.token];
        if (typeof socket!=="undefined")
            invoke(name, socket);
        else
            addToken(eventDef.token, name);
        return {token:eventDef.token};
        // finally...
    },
    unlisten(eventObj){
        delete addresses[eventObj.opts.addresses];
    },
    async init(_ctx, _subsystems){
        console.log("chance module loading...");

        ctx=_ctx; subsystems=_subsystems;

        let chances = await subsystems.db.Events.getAll({type: "chance"});
        for (let eventObj of chances) {
            console.log(`chance ${eventObj.name}, token:${eventObj.opts.token}`);
            addToken(eventObj.opts.token,eventObj.name);
        }

        let io = socket(_ctx.server);
        io.on('connection', function (socket) {
            console.log("connection established, wait for tokenify...")
            socket.on("tokenify", (token)=>{
                console.log("* chance:",token);

                connecting[token]=socket;
                socket.on('disconnect', ()=>{delete connecting[token]});

                let eNames=waitList[token];
                if (typeof eNames!=="undefined"){
                    for (let eName of eNames)
                        invoke(eName, socket);
                    delete waitList[token];
                }
            });
        });
    }
}
